package umage.core;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;


public class ResourceList {
	
	public static Collection<String> getPackageResources(String packageName) {
		return getPackageResources(packageName, "");
	}
	
	public static Collection<String> getPackageResources(String packageName, String extensionFilter) {
		packageName = packageName.replace('.', '/');
		Pattern pattern = null;
		try {
			pattern = Pattern.compile(".*" + packageName + "/[^/]*" + extensionFilter);
		} catch (PatternSyntaxException ex) {
			System.err.println("Invalid Package: " + packageName);
			return Collections.emptyList();
		}
		return getResources(pattern);
	}
	
	public static Collection<String> getResources(Pattern pattern) {
		ArrayList<String> result = new ArrayList<String>();
		
		String[] classPathElements = System.getProperty("java.class.path", ".").split(File.pathSeparator);
		for (String element : classPathElements) {
			File file = new File(element);
			if (file.isDirectory()) {
				result.addAll(getResourcesFromDir(file, pattern));
			} else {
				result.addAll(getResourcesFromJar(file, pattern));
			}
		}
		return result;
	}
	
	private static Collection<String> getResourcesFromJar(File file, Pattern pattern) {
		ArrayList<String> result = new ArrayList<String>();
		ZipFile zipFile = null;
		try {
			zipFile = new ZipFile(file);
			Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
			while (zipEntries.hasMoreElements()) {
				ZipEntry zipEntry = zipEntries.nextElement();
				String fileName = standardizePath(zipEntry.getName());
				if (pattern.matcher(fileName).matches()) {
					result.add(stripPath(fileName));
				}
			}
			return result;
		} catch (Exception e) {
			return result;
		} finally {
			if (zipFile != null) {
				try { zipFile.close(); } catch (Exception e1) {}
			}
		}
	}
	
	private static Collection<String> getResourcesFromDir(File dir, Pattern pattern) {
		ArrayList<String> result = new ArrayList<String>();
		File[] fileList = dir.listFiles();
		for (File file : fileList) {
			if (file.isDirectory()) {
				result.addAll(getResourcesFromDir(file, pattern));
			} else {
				String fileName;
				try {
					fileName = standardizePath(file.getCanonicalPath());
					if (pattern.matcher(fileName).matches()) {
						result.add(stripPath(fileName));
					}
				} catch (Exception e) {}
			}
		}
		return result;
	}
	
	private static String stripPath(String target) {
		int seperationPoint = Math.max(target.lastIndexOf('/'), target.lastIndexOf('\\'));
		if (seperationPoint != -1) {
			return target.substring(seperationPoint + 1);
		} else return target;
	}
	
	private static String standardizePath(String path) {
		return path.replace('\\', '/');
	}
}
